package com.diko.product.service.impl;

import com.diko.product.dao.SpuInfoDao;
import com.diko.product.entity.*;
import com.diko.product.service.*;
import com.diko.product.vo.SpuVo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.diko.common.utils.PageUtils;
import com.diko.common.utils.Query;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuInfoDescService spuInfoDescService;

    @Autowired
    private SpuImagesService spuImagesService;

    @Autowired
    private AttrService attrService;

    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Autowired
    private SkuInfoService skuInfoService;

    @Autowired
    private SkuImagesService skuImagesService;

    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveSpuInfo(SpuSaveVo spuSaveVo) {
        /**
         * 1.保存spu基本信息 pms_spu_info
         * */
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(spuSaveVo,spuInfoEntity);
        //spuInfoEnity和spuSaveVo的区别是前者多了createTime和updateTime
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());

        //自定义的saveBaseSpuInfo()方法
        this.baseMapper.insert(spuInfoEntity);

        /**
         * 2.保存spu的描述图片(desc) pms_spu_info_desc
         * */
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        //取出的是list数组
        List<String> decript = spuSaveVo.getDecript();
        //利用String.join(",")方法，将数组以","分割
        spuInfoDescEntity.setDecript(String.join(",",decript));
        //spuSaveVo无法获取到spuId，可以通过spuInfoEntity来获取
        spuInfoDescEntity.setSpuId(spuInfoEntity.getId());

        //当前是再spuInfo的service里，没有保存desc的mybatis-plus，要再desc的service里创建一个方法保存
        //这里desc里面的方法只有insert，与下面保存图片不同是因为最好不要传入spuInfoVo,这样会使方法没有普遍性
        spuInfoDescService.saveSpuInfoDesc(spuInfoDescEntity);

        /**
         * 3.保存spu的图片集(images) pms_spu_images
         * */
        List<String> images = spuSaveVo.getImages();

        //这里与上面保存desc不同的是，这里的每一个图片都对应一个spuId
        spuImagesService.saveImages(spuInfoEntity.getId(),images);

        /**
         * 4.保存spu的规格参数(baseAttrs) pms_product_attr_value
         * */
        List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();

        List<ProductAttrValueEntity> collect = baseAttrs.stream().map(attr -> {
            ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
            productAttrValueEntity.setAttrId(attr.getAttrId());
            //根据属性id获取属性名
            AttrEntity attrEntity = attrService.getById(attr.getAttrId());
            productAttrValueEntity.setAttrName(attrEntity.getAttrName());

            productAttrValueEntity.setAttrValue(attr.getAttrValues());
            productAttrValueEntity.setQuickShow(attr.getShowDesc());
            productAttrValueEntity.setSpuId(spuInfoEntity.getId());

            //以上的设值，是根据baseAttrs的属性字段来逐个保存到ProductAttrValueEntity里的，其他剩下就不填
            return productAttrValueEntity;
        }).collect(Collectors.toList());

        productAttrValueService.saveProductAttr(collect);

        /**
         * 5.保存spu的积分信息(bounds) sms_spu_bounds
         * */


        /**
         * 6.保存当前spu对应的所有sku信息(sku) pms_sku_info
         * */
            //6.1 sku的基本信息 pms_sku_info
        List<Skus> skus = spuSaveVo.getSkus();
        //一定要判空
        if(skus!=null&&skus.size()>0){
            skus.forEach(item->{
                String defaultImg="";
                for(Images image:item.getImages()){
                    //在defaultImg为1时，表示有imgUrl，可以放入
                    //defaultImg是用于存储，下面会存到entity中
                    if(image.getDefaultImg()==1){
                        defaultImg=image.getImgUrl();
                    }
                }

                SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                BeanUtils.copyProperties(item,skuInfoEntity);

                //填充skuInfoEntity其他缺少的属性值
                skuInfoEntity.setBrandId(spuSaveVo.getBrandId());
                skuInfoEntity.setCatalogId(spuSaveVo.getBrandId());

                skuInfoEntity.setSaleCount(0L);
                skuInfoEntity.setSpuId(spuInfoEntity.getId());
                //这里defaultImg就用上了
                skuInfoEntity.setSkuDefaultImg(defaultImg);

                skuInfoService.saveSkuInfo(skuInfoEntity);
                //存sku进数据库的时候会自动分配一个skuId，后面获取到，有用
                Long skuId = skuInfoEntity.getSkuId();

                //6.2 sku的图片信息 ptms_sku_image
                List<SkuImagesEntity> imagesEntityList = item.getImages().stream().map(img -> {
                    SkuImagesEntity skuImagesEntity = new SkuImagesEntity();

                    skuImagesEntity.setSkuId(skuId);
                    skuImagesEntity.setDefaultImg(img.getDefaultImg());
                    skuImagesEntity.setImgUrl(img.getImgUrl());

                    return skuImagesEntity;
                }).filter(imageEntity -> {
                    //过滤掉为空的图片，也就是“未勾选”的意思
                    return (!StringUtils.isEmpty(imageEntity.getImgUrl()));
                }).collect(Collectors.toList());

                //this.saveBatch()和this.baseMapper.insert()的区别
                //service层可以直接save(),dao层是insert()
                skuImagesService.saveBatch(imagesEntityList);

                //6.3 sku的销售属性信息 pms_sku_sale_attr_value
                List<Attr> attr = item.getAttr();
                List<SkuSaleAttrValueEntity> skuSaleAttrValueEntityList = attr.stream().map(a -> {
                    SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                    BeanUtils.copyProperties(a, skuSaleAttrValueEntity);
                    skuSaleAttrValueEntity.setSkuId(skuId);

                    return skuSaleAttrValueEntity;
                }).collect(Collectors.toList());

                skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntityList);


                //6.4 sku的优惠、满减信息 sms_sku_ladder/sms_sku_full_reduction/sms_member_price


            });
        }







    }

    /**
     * 1.保存商品spu基本信息 pms_spu_info
     * @param spuInfoEntity
     * */
    private void saveBaseSpuInfo(SpuInfoEntity spuInfoEntity) {
        this.baseMapper.insert(spuInfoEntity);
        log.debug("本次保存商品的id：{}",spuInfoEntity.getId());
    }

    /**
     * 2.保存Spu的描述图片 pms_spu_info_desc
     * */
    private void saveSpuInfoDesc(SpuSaveVo spuSaveVo) {

    }

}